package book;

import constant.Constant;
import utils.AnalyzingBook;
import utils.ScannerSingleton;

import java.io.IOException;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
import java.util.Arrays;
import java.util.Scanner;

public class Library {
    //存储书籍
    public Book[] books;
    //当前有多少本书
    public int bookCount;

    public Scanner scanner;
    private static Library library;
    private AnalyzingBook analyzingBook = new AnalyzingBook();


    public Library(){
        //读
        loadAllBook();
        scanner = ScannerSingleton.getScannerSingleton();
    }
    public static Library getLibrary(){
        if(library == null){
            library = new Library();
        }
        return library;
    }

    private void loadAllBook(){
        try {
            Book[] allBook = analyzingBook.loadObject(Constant.ALL_BOOK_FILE_NAME);
            books = new Book[Constant.CAPACITY];
            if (allBook == null){
                bookCount = 0;
            }else {
                //3. 查看实际书籍⻓度是多少 是否⼤于默认的⻓度5
                int allBookLen = allBook.length;
                //3.1 ⼤于默认⻓度 books数组 分配实际的⼤⼩
                if (allBookLen > books.length) {

                //按照实际情况进⾏分配数组内存
                    books = new Book[allBookLen];
                }
                //3.2 把读到的元素进⾏赋值
                for (int i = 0; i < allBookLen; i++) {
                    books[i] = allBook[i];
                }
                //4.修改实际有效书籍个数
                bookCount = allBookLen;
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    //存储图书到⽂件中
    private void storeBook() {
        try {
            analyzingBook.storeObject(books,Constant.ALL_BOOK_FILE_NAME);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    //公用的方法
    public void searchBook(){
        System.out.println("查找图书");
    }
    public void displayBook(){
        System.out.println("展示图书");

        for (int i = 0; i < bookCount; i++) {
            System.out.println(books[i]);
        }
    }
    public void exit(){
        System.out.println("退出系统");
        System.exit(0);
    }


    public void addBook(Book book){
        System.out.println("Library的add方法执行了");

        if (bookCount >= books.length){
            System.out.println("图书馆已满，无法上架图书");
            //可以自己尝试扩容
            return;
        }


        Book bookLast = books[bookCount-1];
        bookCount++;

        book.setBookId(bookLast.getBookId()+1);

        storeBook();

        System.out.println("图书上架成功");
    }

    public Book searchById(int bookId){
        loadAllBook();
        for (int i = 0; i < bookCount; i++) {
            Book book = books[i];
            if (book.getBookId() == bookId){
                return book;
            }
        }
        return null;
    }

    //根据bookId更新图书
    public void updateBook(Book book) {

        int bookId = book.getBookId();

        int index =searchByIdReturnIndex(bookId);

        if(index == -1){
            System.out.println("没有你要找的这本书"+bookId);
            return;
        }
        //更新的图书覆盖原本的图书
        books[index] = book;
        // 把当前更新的图书写入文件
        storeBook();
        System.out.println("书籍已更新");
    }



    //根据bookId 返回 书籍索引位置
    private int searchByIdReturnIndex(int bookId) {

        loadAllBook();

        for (int i = 0; i < bookCount; i++) {
            Book book = books[i];
            if (book.getBookId() == bookId){
                return i;
            }
        }
        return -1;
    }


    public void removeBook(int bookId){
        loadAllBook();

        int index =searchByIdReturnIndex(bookId);
        //防御性编程
        if(index == -1){
            System.out.println("没有你要找的这本书");
            return;
        }

        for (int i = index; i < bookCount - 1; i++) {
            books[i] = books[i+1];
        }
        //把原本最后一个书改变成null
        books[bookCount - 1] = null;
        //使原本的容量-1
        bookCount--;


        storeBook();


    }

    public void borrowCount() {
        loadAllBook();
        for (int i = 0; i < bookCount; i++) {
            Book book = books[i];
            System.out.println("书籍"+book.getTitle()+"借阅了"+book.getBorrowCount()+"次");
        }
    }

    public void generateBook(int k) {
        loadAllBook();
        Book[] tmp = new Book[bookCount];
        for (int i = 0; i < bookCount; i++) {
            tmp[i] = books[i];
        }
//2.1 开始排序
        Arrays.sort(tmp);
//3. 把前k本书拷⻉到新数组 可以不定义临时数组，直接输出前K个就⾏
        Book[] generateBooks = new Book[k];
        for (int i = 0; i < k; i++) {
            generateBooks[i] = tmp[i];
        }
//4.打印新数组
        System.out.println("最受欢迎书籍如下：");
        for (int i = 0; i < generateBooks.length; i++) {
            Book book = generateBooks[i];
            System.out.println("书籍ID: "+i+" 书名："+ book.getTitle()+" 作者："+
                    book.getTitle()+" 借阅次数："+book.getBorrowCount());
        }
    }

    public void checkInventoryStatus() {
        loadAllBook();
        for (int i = 0; i < bookCount; i++) {
            Book book = books[i];

            String borrow = "未借出";
            if(book.isBorrowed()){
                borrow = "已借出";
            }
            System.out.println("书籍"+book.getTitle()+"借阅状态"+borrow);
        }
    }

    public void checkAndRemoveOldBooks() {
        loadAllBook();
        // 获取当前时间戳
        long currentTimestamp = System.currentTimeMillis();
        // 将当前时间戳转换为 LocalDate
        LocalDate currentDate = Instant.ofEpochMilli(currentTimestamp)
                .atZone(ZoneId.systemDefault())
                .toLocalDate();
        boolean flg = false;
        for (int i = 0; i <bookCount; i++) {
            Book book = books[i];
//获取当前书籍的上架时间
            LocalDate specifiedDate = book.getShelfDate();
// 计算两个⽇期之间的差值（以年为单位）
            long yearsBetween = ChronoUnit.YEARS.between(specifiedDate,
                    currentDate);
            if(yearsBetween >= 1) {
                System.out.print("图书 " + book.getTitle() + " 已经上架超过⼀年，是否 移除？ (y/n)：");

                scanner.nextLine();
                String response = scanner.nextLine();
                scanner.nextLine();

                if ("y".equals(response)) {
                //确认删除调⽤remove⽅法进⾏删除
                    removeBook(book.getBookId());
                    System.out.println("removeBook执行了");
                    i--; // 因为后⾯的书已经向前移动，所以要重新检查当前索引位置
                }
                flg = true;
            }
        }
        if(!flg) {
            System.out.println("没有上架超过⼀年的图书！");
        }
    }

    public void categorizeBooksByCategory() {
        loadAllBook();
        // 第⼀步：找出所有唯⼀的类别
        String[] uniqueCategories = new String[books.length];
        //不重复的类别的个数 相当于uniqueCategories 数组的下标
        int uniqueCategoryCount = 0;
        for (int j = 0; j < bookCount;j++) {
            Book book = books[j];
            String category = book.getCategory();
            boolean found = false;
            //遍历 uniqueCategories 数组 检查是否已经存在该类别
            for (int i = 0; i < uniqueCategoryCount; i++) {
                if (uniqueCategories[i].equals(category)) {
                    found = true;
                    break;
                }
            }
//如果这⾥是false说明没有进去循环，说明 uniqueCategories 数组中不存在该类别
            if (!found) {
                uniqueCategories[uniqueCategoryCount] = category;
//不重复的类别需要加加
                uniqueCategoryCount++;
            }
        }

        // 这⾥完成后，uniqueCategories 数组中存放了所有唯一的类别
        // 第⼆步：创建 categoryCount 数组并计数
        // 创建一个长度为 uniqueCategoryCount 的 PairOfCategory 数组，用于存储每个类别及其对应的书籍数量
// 第⼆步：创建categoryCount数组并计数
        PairOfCategory[] categoryCounts = new PairOfCategory[uniqueCategoryCount];
//默认给每⼀种类型 设置为 0 ⽐如：编程:0 ⼩说:0
        for (int i = 0; i < uniqueCategoryCount; i++) {
            categoryCounts[i] = new PairOfCategory(uniqueCategories[i], 0);
        }
//开始统计种类出现的次数
        for (int j = 0; j < bookCount;j++) {
//获取每⼀本书籍对象
            Book book = books[j];
//获取该书籍对象的种类
            String category = book.getCategory();
//假设category为⼩说，则遍历categoryCounts数组，找到⼩说，则⾃增

            for (int i = 0; i < categoryCounts.length; i++) {
                PairOfCategory categoryCount = categoryCounts[i];
                if (categoryCount.getCategory().equals(category)) {
                    categoryCount.incrementCount();
                    break;
                }

            }

        }
        /* for (PairOfCategory categoryCount : categoryCounts) {
                if (categoryCount.getCategory().equals(category)) {
                    categoryCount.incrementCount();
                    break;
                }
            }*/


// 打印结果
        for (int i = 0; i < categoryCounts.length; i++) {
            PairOfCategory pairOfCategory = categoryCounts[i];
            System.out.println(pairOfCategory.getCategory()+": "+pairOfCategory.getCategoryCount());
        }

    }

    public void categorizeBooksByAuthor() {
        loadAllBook();
        //第一步：找出所有唯一的类别
        String[] uniqueAuthor = new String[books.length];
        //不重复的类别的个数  相当于uniqueAuthor 数组的下标
        int uniqueAuthorCount = 0;
        for (int j = 0; j < bookCount; j++) {
            Book book = books[j];
            String author = book.getAuthor();
            boolean found = false;
            //遍历uniqueAuthorCount数组，
            for (int i = 0; i < uniqueAuthorCount; i++) {
                if(uniqueAuthor[i].equals(author)){
                    found = true;
                    break;
                }
            }
            //
            if(!found){
                uniqueAuthor[uniqueAuthorCount] = author;
                uniqueAuthorCount++;
            }
        }
        PairOfAuthor[] authorCounts = new PairOfAuthor[uniqueAuthorCount];

        for (int i = 0; i < uniqueAuthorCount; i++) {
            authorCounts[i] = new PairOfAuthor(uniqueAuthor[i],0);

        }
        for (int j = 0; j <bookCount ; j++) {
            Book book = books[j];

            String author = book.getAuthor();


            for (int i = 0; i < authorCounts.length; i++) {
                PairOfAuthor pairOfAuthor = authorCounts[i];
                if (pairOfAuthor.getAuthor().equals(author)) {
                    pairOfAuthor.incrementCount();
                    break;
                }

            }



        }


        /*for (PairOfAuthor pairOfAuthor : authorCounts) {
                if (pairOfAuthor.getAuthor().equals(author)) {
                    pairOfAuthor.incrementCount();
                    break;
                }
            }*/
        for (int i = 0; i < authorCounts.length; i++) {
            PairOfAuthor author1 = authorCounts[i];
            System.out.println(author1.getAuthor()+": "+author1.AuthorCount);
        }

    }

    public void returnBook(int  bookId) {
        loadAllBook();
        for (int i = 0; i < bookCount; i++) {
            Book book = books[i];
            if(book.getBookId()==bookId) {
                book.setBorrowed(false);
            }
        }
        storeBook();
    }
/*
    public int getbookCount() {
        loadAllBook();
        return bookCount;
    }*/


    public class PairOfAuthor{

        private String Author;

        private int AuthorCount;

        public PairOfAuthor(String author, int authorCount) {
            Author = author;
            AuthorCount = authorCount;
        }

        public String getAuthor() {
            return Author;
        }

        public void setAuthor(String author) {
            Author = author;
        }

        public int getAuthorCount() {
            return AuthorCount;
        }

        public void setAuthorCount(int authorCount) {
            AuthorCount = authorCount;
        }
        public void incrementCount(){
            this.AuthorCount++;
        }


    }


    public class PairOfCategory{

        //类别
        private String category;
        //该类别的数量
        private int categoryCount;

        public PairOfCategory(String category, int categoryCount) {
            this.category = category;
            this.categoryCount = categoryCount;
        }

        public String getCategory() {
            return category;
        }

        public void setCategory(String category) {
            this.category = category;
        }

        public int getCategoryCount() {
            return categoryCount;
        }

        public void setCategoryCount(int categoryCount) {
            this.categoryCount = categoryCount;
        }

        public void incrementCount() {
            this.categoryCount++;
        }
    }
   /* public boolean searchByIdReturnIsBorrowed(int borrowBookId) {

        loadAllBook();

        for (int i = 0; i < bookCount; i++) {
            Book book = books[i];
            if (book.getBookId() == borrowBookId){
                if(book.isBorrowed() == true){
                    return true;
                }
            }
        }
        return false;
    }*/

    /*public class PairOfUidAndBookId {
        private int userId;

        private int bookId;

        public PairOfUidAndBookId(int userId, int bookId) {
            this.userId = userId;
            this.bookId = bookId;
        }

        public int getUserId() {
            return userId;
        }

        public void setUserId(int userId) {
            this.userId = userId;
        }

        public int getBookId() {
            return bookId;
        }

        public void setBookId(int bookId) {
            this.bookId = bookId;
        }

        public String toJson() {
            StringBuilder json = new StringBuilder();
            json.append(userId).append(",");
            json.append(bookId);
            return json.toString();
        }
    }*/


    public void borrowBook(int bookId){
        loadAllBook();
        for (int i = 0; i <bookCount; i++) {
            Book book = books[i];
            if(book.getBookId()== bookId) {
                book.setBorrowed(true);
                book.incrementBorrowCount();
            }
        }
        storeBook();
    }



}
